﻿Namespace Validation
    Public Class TypeValidationRuleSetter
        Inherits WPFGlue.Validation.ValidationRuleSetter

        Private _ReferenceType As Type
        Private _DummyObject As Object
        Public Property ReferenceType As Type
            Get
                Return _ReferenceType
            End Get
            Set(ByVal value As Type)
                If value IsNot Nothing AndAlso value IsNot _ReferenceType Then
                    _ReferenceType = value
                    Dim defaultConstructor As System.Reflection.ConstructorInfo = _ReferenceType.GetConstructor(System.Type.EmptyTypes)
                    If defaultConstructor IsNot Nothing Then
                        _DummyObject = defaultConstructor.Invoke(Nothing)
                    Else
                        _DummyObject = New Object
                    End If
                End If
            End Set
        End Property
        Protected Overrides ReadOnly Property DummyDataContext As Object
            Get
                Return _DummyObject
            End Get
        End Property


        Public Property DateMessage As String = "Must be a date value."

        Public Property IntegerMessage As String = "Must be an integer between {1} and {2}."

        Public Property NumericMessage As String = "Must be a number between {1} and {2}."

        Protected Overrides Sub AttachRules(ByVal base As Object)
            Dim f As FrameworkElement = TryCast(base, FrameworkElement)
            If f IsNot Nothing And ReferenceType IsNot Nothing Then
                If f IsNot Nothing Then
                    Dim bg As BindingGroup = f.BindingGroup
                    If bg IsNot Nothing Then
                        For Each be As BindingExpression In bg.BindingExpressions.OfType(Of BindingExpression)()
                            Dim propertyName = be.ParentBinding.Path.Path
                            Dim propertyInfo As System.Reflection.PropertyInfo = ReferenceType.GetProperty(propertyName)
                            Select Case propertyInfo.PropertyType
                                Case GetType(DateTime)
                                    be.ParentBinding.ValidationRules.Add(New DateValidationRule(Me.DateMessage))
                                Case GetType(Int16)
                                    be.ParentBinding.ValidationRules.Add(New IntegerValidationRule(Int16.MinValue, Int16.MaxValue, Me.IntegerMessage))
                                Case GetType(Int32)
                                    be.ParentBinding.ValidationRules.Add(New IntegerValidationRule(Int32.MinValue, Int32.MaxValue,Me.IntegerMessage))
                                Case GetType(Int64)
                                    be.ParentBinding.ValidationRules.Add(New IntegerValidationRule(Int64.MinValue, Int64.MaxValue, Me.IntegerMessage))
                                Case GetType(Single)
                                    be.ParentBinding.ValidationRules.Add(New NumericValidationRule(Single.MinValue, Single.MaxValue,Me.NumericMessage))
                                Case GetType(Double)
                                    be.ParentBinding.ValidationRules.Add(New NumericValidationRule(Double.MinValue, Double.MaxValue, Me.NumericMessage))
                                Case GetType(Decimal)
                                    be.ParentBinding.ValidationRules.Add(New NumericValidationRule(Decimal.MinValue, Decimal.MaxValue, Me.NumericMessage))
                                Case GetType(Integer)
                                    be.ParentBinding.ValidationRules.Add(New IntegerValidationRule(Integer.MinValue, Integer.MaxValue, Me.IntegerMessage))
                            End Select
                            If Setters.Contains(propertyName) Then
                                For Each v As System.Windows.Controls.ValidationRule In Setters.Item(propertyName).ValidationRules
                                    be.ParentBinding.ValidationRules.Add(v)
                                Next
                            End If
                        Next
                    End If
                End If
            End If
        End Sub
    End Class
End Namespace
